/* combi_pic.cpp */

#include <dodo_plot/kernel/combi_pic.h>
#include <dodo_plot/kernel/basic_utils.h>
#include <dodo_plot/kernel/plotter.h>
#include <algorithm>

namespace dodo_plot
{

Combi_Pic::Combi_Pic(const Picture& lower, const Picture& upper,
                     double x_offset, double y_offset)
		: l_(lower), u_(upper), offset_(x_offset, y_offset)
{
}

Combi_Pic::Combi_Pic(const Picture& lower, const Picture& upper, int mode, double extra_x_offset, double extra_y_offset)
		: l_(lower), u_(upper)
{
	set_offset(mode, extra_x_offset, extra_y_offset);
}

double Combi_Pic::height() const
{
	switch(size_lock_) 
	{
	case LOCK_L:
	       return l_.height(); break;
	case LOCK_U:
	       return u_.height(); break;
	default:
	       return std::max(l_.height(), u_.height() + offset_.y) - std::min(0.0, offset_.y);
	}
}

double Combi_Pic::width() const
{
	switch(size_lock_)
	{
	case LOCK_L:
	       return l_.width(); break;
	case LOCK_U:
	       return u_.width(); break;
	default:
	       return std::max(l_.width(), u_.width() + offset_.x) - std::min(0.0, offset_.x);
	}
}

Position Combi_Pic::local_pos() const
{
	return Position(0.0, width(), 0.0, height());
}

void Combi_Pic::draw(const Plotter& plotter) const
{
	Point l_offset;
	Point u_offset;
	
	switch(size_lock_)
	{
	case LOCK_L:
		l_offset = Point(0, 0);
		u_offset = offset_;
		break;
	case LOCK_U:
		l_offset = -offset_;
		u_offset = Point(0, 0);
		break;
	default:
		if (offset_.x >= 0)
		{
			l_offset.x = 0;
			u_offset.x = offset_.x;
		}
		else
		{
			l_offset.x = -offset_.x;
			u_offset.x = 0;
		}

		if (offset_.y >= 0)
		{
			l_offset.y = 0;
			u_offset.y = offset_.y;
		}
		else
		{
			l_offset.y = -offset_.y;
			u_offset.y = 0;
		}

	}
	Position l_pos = Position(
		l_offset.x,
		l_offset.x + l_.width(), 
		l_offset.y,
		l_offset.y + l_.height()
		);
	Position u_pos = Position(
		u_offset.x,
		u_offset.x + u_.width(), 
		u_offset.y,
		u_offset.y + u_.height()
		);

	plotter.begin_new_path();
	l_.draw(plotter.sub_plotter(l_pos, l_.local_pos()));
	u_.draw(plotter.sub_plotter(u_pos, u_.local_pos()));
}

Point Combi_Pic::center_offset() const
{
	return Point(
	               (l_.width() - u_.width()) / 2 - offset_.x,
	               (l_.height() - u_.height()) / 2 - offset_.y
	       );
}

void Combi_Pic::set_offset(int mode, double extra_x_offset, double extra_y_offset)
{
	int pos_mode = mode & ~SIZE_LOCK & ~SIZE_LOCK_2;

	switch (pos_mode)
	{
	case CENTER:
		offset_.x = (l_.width() - u_.width()) / 2;
		offset_.y = (l_.height() - u_.height()) / 2;
		break;
	case LEFT:
		offset_.x = - u_.width();
		offset_.y = (l_.height() - u_.height()) / 2;
		break;
	case RIGHT:
		offset_.x = l_.width();
		offset_.y = (l_.height() - u_.height()) / 2;
		break;
	case TOP:
		offset_.x = (l_.width() - u_.width()) / 2;
		offset_.y = - u_.height();
		break;
	case BOTTOM:
		offset_.x = (l_.width() - u_.width()) / 2;
		offset_.y = l_.height();
		break;
	case LEFT_INSIDE:
		offset_.x = 0;
		offset_.y = (l_.height() - u_.height()) / 2;
		break;
	case RIGHT_INSIDE:
		offset_.x = l_.width() - u_.width();
		offset_.y = (l_.height() - u_.height()) / 2;
		break;
	case TOP_INSIDE:
		offset_.x = (l_.width() - u_.width()) / 2;
		offset_.y = 0;
		break;
	case BOTTOM_INSIDE:
		offset_.x = (l_.width() - u_.width()) / 2;
		offset_.y = l_.height() - u_.height();
		break;
	case LEFT_TOP:
		offset_.x = - u_.width();
		offset_.y = 0;
		break;
	case LEFT_BOTTOM:
		offset_.x = - u_.width();
		offset_.y = l_.height() - u_.height();
		break;
	case RIGHT_TOP:
		offset_.x = l_.width();
		offset_.y = 0;
		break;
	case RIGHT_BOTTOM:
		offset_.x = l_.width();
		offset_.y = l_.height() - u_.height();
		break;
	case TOP_LEFT:
		offset_.x = 0;
		offset_.y = - u_.height();
		break;
	case TOP_RIGHT:
		offset_.x = l_.width() - u_.width();
		offset_.y = - u_.height();
		break;
	case BOTTOM_LEFT:
		offset_.x = 0;
		offset_.y = l_.height();
		break;
	case BOTTOM_RIGHT:
		offset_.x = l_.width() - u_.width();
		offset_.y = l_.height();
		break;
	case LEFT_TOP_INSIDE:
		offset_.x = 0;
		offset_.y = 0;
		break;
	case LEFT_BOTTOM_INSIDE:
		offset_.x = 0;
		offset_.y = l_.height() - u_.height();
		break;
	case RIGHT_TOP_INSIDE:
		offset_.x = l_.width() - u_.width();
		offset_.y = 0;
		break;
	case RIGHT_BOTTOM_INSIDE:
		offset_.x = l_.width() - u_.width();
		offset_.y = l_.height() - u_.height();
		break;
	case LEFT_TOP_OUT_CORNER:
		offset_.x = - u_.width();
		offset_.y = - u_.height();
		break;
	case LEFT_BOTTOM_OUT_CORNER:
		offset_.x = - u_.width();
		offset_.y = l_.height();
		break;
	case RIGHT_TOP_OUT_CORNER:
		offset_.x = l_.width();
		offset_.y = - u_.height();
		break;
	case RIGHT_BOTTOM_OUT_CORNER:
		offset_.x = l_.width();
		offset_.y = l_.height();
		break;
	default:
		;
	}
	offset_.x += extra_x_offset;
	offset_.y += extra_y_offset;

	if (mode & SIZE_LOCK)
		size_lock_ = LOCK_L;
	else if(mode & SIZE_LOCK_2)
		size_lock_ = LOCK_U;
	else
		size_lock_ = NO_LOCK;
}


}
